

import javax.sound.midi.Instrument;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Synthesizer;

import net.java.games.input.Component;
import net.java.games.input.Controller;
import net.java.games.input.ControllerEnvironment;
import net.java.games.input.Component.Identifier;

@SuppressWarnings("unused")
public class GuitarHero360 {


	public static void main(String []args) throws InvalidMidiDataException,
			MidiUnavailableException, InterruptedException
		{
		
		int trans = 0;
		int min = -1;
		//Synth shit.
		MidiDevice.Info[] mdi = MidiSystem.getMidiDeviceInfo();
		Synthesizer synth = MidiSystem.getSynthesizer();
   		synth.open();
	    final MidiChannel[] mc = synth.getChannels();
	    
	    Instrument[] instr = synth.getDefaultSoundbank().getInstruments();
	    synth.loadInstrument(instr[79]);
	    
		//gets and prints Midi Ports info
		MidiDevice.Info[] info = MidiSystem.getMidiDeviceInfo();
		
		for(int i = 0; i < info.length;i++ ){
			System.out.println("Midi comp "+i+" is "+info[i]);
		}
		System.out.println();
		
		//Sets output device
		MidiDevice mapleOut = MidiSystem.getMidiDevice(info[6]);
		mapleOut.open();
		
		Receiver rec = mapleOut.getReceiver();
		
		//Sets Notes
		ShortMessage noteOff = new ShortMessage();
		ShortMessage doe = new ShortMessage();
		ShortMessage rae = new ShortMessage();
		ShortMessage me = new ShortMessage();
		ShortMessage fa = new ShortMessage();
		ShortMessage so = new ShortMessage();
		ShortMessage la = new ShortMessage();
		ShortMessage ti = new ShortMessage();
		ShortMessage doe2 = new ShortMessage();
		ShortMessage rae2 = new ShortMessage();
		ShortMessage me2 = new ShortMessage();
		ShortMessage fa2 = new ShortMessage();
		ShortMessage so2 = new ShortMessage();
		ShortMessage la2 = new ShortMessage();
		ShortMessage ti2 = new ShortMessage();
		ShortMessage doe3 = new ShortMessage();

		noteOff.setMessage(128 , 0 , 0 );
		doe.setMessage(ShortMessage.NOTE_ON, 60+trans, 100);
		rae.setMessage(ShortMessage.NOTE_ON, 62+trans, 127);
		me.setMessage(ShortMessage.NOTE_ON, 64+min+trans, 100);
		fa.setMessage(ShortMessage.NOTE_ON, 65+trans, 100);
		so.setMessage(ShortMessage.NOTE_ON, 67+trans, 100);
		la.setMessage(ShortMessage.NOTE_ON, 69+min+trans, 100);
		ti.setMessage(ShortMessage.NOTE_ON, 71+min+trans, 100);
		doe2.setMessage(ShortMessage.NOTE_ON, 72+trans, 100);
		rae2.setMessage(ShortMessage.NOTE_ON, 74+trans, 100);
		me2.setMessage(ShortMessage.NOTE_ON, 76+min+trans, 100);
		fa2.setMessage(ShortMessage.NOTE_ON, 77+trans, 100);
		so2.setMessage(ShortMessage.NOTE_ON, 79+trans, 100);
		la2.setMessage(ShortMessage.NOTE_ON, 81+min+trans, 100);
		ti2.setMessage(ShortMessage.NOTE_ON, 83+min+trans, 100);
		doe3.setMessage(ShortMessage.NOTE_ON, 84+trans, 100);
		
		System.out.println("Using "+mapleOut.getDeviceInfo());
		System.out.println();
		
		//Controller set up
		ControllerEnvironment ce =
			ControllerEnvironment.getDefaultEnvironment();

		// retrieve the available controllers
		Controller[] controllers = ce.getControllers();
		
		int q = 0;
		for(Controller c : controllers){
			System.out.println(q+" Name: " + c.getName() + " type: " + c.getType());
			q++;
		}
		System.out.println();
		
		
		//fetch gamepad controller
		Controller controller = controllers[4];
		
		//Make Array of Components and prints it
		Component[] comps = controller.getComponents();
		for(int i = 0; i < comps.length; i++){
			System.out.println("Component "+i+" is "+comps[i]);
		}
		System.out.println();
		boolean[] buttons = getButtons(comps,controller);
		boolean strum;
		
		//Component A = comps[5];
		//Component B = comps[6];
		
		Component B = comps[2];
		while(controller.poll()){
			System.out.println(B.getPollData());
		}
		
		
		int lastNote = 60;
		
		boolean test = true;
		while(true){
			buttons = getButtons(comps,controller);
			strum = getHat(comps,controller);

			if(buttons[7]){
				System.exit(-1);
			}
			if(buttons[0] && buttons[1] && buttons[3] && strum){
				if(test){
					Thread.sleep(5);
					rec.send(noteOff, -1);
					Thread.sleep(5);
					rec.send(doe2,-1);
					lastNote = doe2.getData1();
					test = false;
				}
			}else if(buttons[0] && buttons[1] && strum){
				if(test){
					Thread.sleep(5);
					noteOff.setMessage(128 , lastNote , 0 );
					rec.send(noteOff, -1);
					Thread.sleep(5);
					rec.send(fa,-1);
					lastNote = fa.getData1();
					test = false;
				}
			}else if(buttons[0] && buttons[3] && strum){
				if(test){
					Thread.sleep(5);
					noteOff.setMessage(128 , lastNote , 0 );
					rec.send(noteOff, -1);
					Thread.sleep(5);
					rec.send(la,-1);
					lastNote = la.getData1();
					test = false;
				}
			}else if(buttons[1] && buttons[3] && strum){
				if(test){
					Thread.sleep(5);
					noteOff.setMessage(128 , lastNote , 0 );
					rec.send(noteOff, -1);
					Thread.sleep(5);
					rec.send(ti,-1);
					lastNote = ti.getData1();
					test = false;
				}
			}else if(buttons[3] && strum){
				if(test){
					Thread.sleep(5);
					noteOff.setMessage(128 , lastNote , 0 );
					rec.send(noteOff, -1);
					Thread.sleep(5);
					rec.send(so,-1);
					lastNote = so.getData1();
					test = false;
				}
			}else if(buttons[1] && strum){
				if(test){
					Thread.sleep(5);
					noteOff.setMessage(128 , lastNote , 0 );
					rec.send(noteOff, -1);
					Thread.sleep(5);
					rec.send(me,-1);
					lastNote = me.getData1();
					test = false;
				}
			}else if(buttons[0] && strum){
				if(test){
					Thread.sleep(5);
					noteOff.setMessage(128 , lastNote , 0 );
					rec.send(noteOff, -1);
					Thread.sleep(5);
					rec.send(rae,-1);
					lastNote = rae.getData1();
					test = false;
				}
			}else if(strum){
				if(test){
					Thread.sleep(5);
					noteOff.setMessage(128 , lastNote , 0 );
					rec.send(noteOff, -1);
					Thread.sleep(5);
					rec.send(doe,-1);
					lastNote = doe.getData1();
					test = false;
				}
			}else if(!test){
				Thread.sleep(5);
				noteOff.setMessage(128 , lastNote , 0 );
				rec.send(noteOff, -1);
				test = true;
			}
		}
	}
	
	
	public static boolean getHat(Component[] comps,Controller controller){
		boolean hat = false; 
		controller.poll();
		//for(int i = 0; i < 3; i++){
			if((comps[15]).getPollData() != 0){
				hat = true;
			//}
		}
		return hat;
	}
	
	public static boolean[]getButtons(Component[] comps,Controller controller){
		boolean[] buttons = new boolean[13];
		float value;
		controller.poll();
		for(int i = 5; i <= 14; i++){
			value = comps[i].getPollData();
			buttons[i-5] = (value != 0.0f);
		}
		return buttons;
	}
}


